package com.rraj.common.mq;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.transaction.LocalTransactionChecker;
import com.aliyun.openservices.ons.api.transaction.TransactionStatus;
import com.xiaoleilu.hutool.date.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * Created by WangSheng on 2017/6/8.
 *
 * @author WangSheng
 * @date 2017/06/08
 */
@Component
public class MQLocalTransactionCheckerImpl implements LocalTransactionChecker,ApplicationContextAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(MQLocalTransactionCheckerImpl.class);
    @Override
    public TransactionStatus check(Message message) {
        TransactionStatus transactionStatus = TransactionStatus.Unknow;
        try {
            boolean isCommit = check(message.getUserProperties(MQConstant.TRANSACTION_TYPE_KEY));
            if (isCommit) {
                //本地事务已成功、提交消息
                transactionStatus = TransactionStatus.CommitTransaction;
                LOGGER.info(DateUtil.now() + " 本地事务回调检测成功, Topic is:" +
                    message.getTopic() + ", MsgId is:" + message.getMsgID() + ",message body:" + new String(message.getBody(),"UTF-8"));
            } else {
                //本地事务已失败、回滚消息
                transactionStatus = TransactionStatus.RollbackTransaction;
                LOGGER.info(DateUtil.now() + " 本地事务回调检测失败, Topic is:" +
                    message.getTopic() + ", MsgId is:" + message.getMsgID() + ",message body:" + new String(message.getBody(),"UTF-8"));
            }
        } catch (Exception e) {
        }
        return transactionStatus;
    }

    private ApplicationContext applicationContext;

    /**
     * 检查本地事务是否执行成功
     * @param key 本地事务检查调回类在spring容器中对应的名称
     * @return
     */
    private boolean check(String key){
        MQTransactionChecker handle = (MQTransactionChecker)applicationContext.getBean(key);
        return handle.check();
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
